Java® is a programming language designed to generate applications that can run on all hardware platforms without modification. Java® was modeled after C++, and Java® programs can be called from within hypertext markup language (HTML) documents or launched stand alone. The source code of a Java® program is compiled into an intermediate language called “bytecode,” which cannot run by itself The bytecode is converted (interpreted) into machine code at runtime. When running a Java® application, a Java® interpreter (Java® Virtual Machine (JVM)), is invoked. The JVM translates the bytecode into machine code and runs it. As a result, Java® programs are not dependent on any specific hardware and will run in any computer with the JVM software.
A heap is a memory area, which contains all of the objects created by an application running on the JVM. During the course of executions, some objects may no longer be needed or used by an application. These types of objects are considered old objects. As more objects are created, the amount of space in the heap decreases. At some point in time, it is appropriate or useful to clear out or free objects that are no longer being used by an application. This process is referred to as garbage collection. In other words, the old objects are no longer needed by the program and can be removed. This process involves memory recycling. When an object is old, the space in the heap occupied by this object may be recycled such that the space is made available for subsequent new objects. An object is considered old when the object is no longer referenced by a program or application. A program or application has a reference to an object, which allows the program or application to manipulate the object. A reference is similar to a pointer.
JVMs may be used in various systems, such as an enterprise information system. In such a system, it is important to ensure that the JVMs are operating correctly as undesirable behavior, as discussed below, by the JVMs could have an adverse affect on the enterprise applications or the system itself.
Such undesirable behavior includes out of memory issues and heap fragmentation. For example, the JVM locates a contiguous free space within the heap to allocate an object; if the JVM cannot locate a contiguous free space of sufficient size, then an Out of Memory error is returned to the application running on the JVM. This problem of locating contiguous free space of sufficient size in the heap increases as the size of allocation requests increases. In particular, as the JVM allocates and then deallocates objects within the heap, the free space in the heap becomes fragmented over time, leading to the return of Out of Memory errors when the total free space in the heap is large enough for an object allocation, because there is no contiguous free space large enough for a particular object allocation. For example, because of fragmentation, a heap may include 100 MB total of free space, however, the largest contiguous free space is only 1 MB, leading to the return of an Out of Memory error when the JVM attempts to allocate an object greater than 1 MB.
Another undesirable behavior of the JVM includes excessive garbage collection. As discussed above, garbage collection is a form of automatic memory management. In garbage collection, a garbage collector attempts to reclaim garbage, or memory occupied by objects that are no longer in use by the program. By implementing an excessive amount of garbage collection, the garbage collector may be running too frequently thereby inefficiently using the processor which could be using those cycles for other tasks.
Another undesirable behavior of the JVM includes memory leaks. A memory leak occurs when a program consumes memory but is unable to release it back to the operating system. If too many memory leaks occur, these memory leaks can usurp all of memory and bring everything to a halt or slow the processing considerably. For instance, the JVM allocates and deallocates memory automatically. However, program level leaks can still occur. For example, programming errors can lead to object references still being held in a global data structure, which leads to reduced free space on the heap for allocating new objects.
Furthermore, an undesirable behavior of the JVM may involve the number of objects queued for finalization. Finalization is a feature of the Java® programming language that allows one to perform postmortem cleanup on objects that the garbage collector has found to be unreachable. It is typically used to reclaim native resources associated with an object via a finalize method. If a class has a finalize method, then objects of that type do not have their space reclaimed at garbage collection time. Instead, after garbage collection, the objects are queued for finalization, which occurs sometime later. In the JVM implementation, “finalizers” are executed by a daemon thread that services the finalization queue. If the finalizer thread cannot keep up with the finalization queue, it is possible that the heap will fill up and an Out of Memory error will be issued.
In addition, an undesirable behavior of the JVM may involve an excessive number of compactions. Compaction, performed during garbage collection, refers to moving objects in the heap so that the objects the garbage collector is supposed to reclaim and all remaining objects become contiguous in the heap. That is, compaction optimizes the heap by defragmenting the heap in such a manner that all the live objects are rearranged to have larger contiguous free spaces within the heap. However, by having an excessive number of compactions, the processor is being used inefficiently.
Currently, there are no real-time monitoring tools to monitor such undesirable behavior by the JVMs in real-time. Such behavior, without correcting it, may lead to servers crashing, applications becoming damaged, applications becoming unreliable or unavailable and even manifest itself into a system-wide issue. Since there are no real-time monitoring tools to monitor such behavior, by the time these problems are detected, it may be too late to take remedial action.